package com.msl.debezium.common;

import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@RestControllerAdvice
public class GlobalExceptionHandler {

    private final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    /**
     * 异常捕获
     * @param e
     * @return
     */
    @ExceptionHandler(Exception.class)
    public Msg handlerException(Exception e) {
        ResultCodeEnum resultCodeEnum = ResultCodeEnum.FAIL;
        String message = "";
        if(e instanceof BizException){
            message = e.getMessage();
        }else if(e instanceof ConstraintViolationException){
            //单个参数校验不通过的异常捕获
            ConstraintViolationException c = (ConstraintViolationException) e;
            Set<ConstraintViolation<?>> violations = c.getConstraintViolations();
            StringBuffer errorMsg = new StringBuffer();
            violations.stream().forEach(x -> errorMsg.append(x.getMessage()).append(System.getProperty("line.separator")));
            message = errorMsg.toString();
        } else if(e instanceof MethodArgumentNotValidException){
            //Json请求是校验不通过的异常捕获
            MethodArgumentNotValidException c = (MethodArgumentNotValidException) e;
            List<FieldError> fieldErrors = c.getBindingResult().getFieldErrors();
            StringBuffer errorMsg = new StringBuffer();
            fieldErrors.stream().forEach(x -> errorMsg.append(x.getDefaultMessage()).append(System.getProperty("line.separator")));
            message = errorMsg.toString();
        } else {
            resultCodeEnum = ResultCodeEnum.SERVER_ERROR;
            message = "发生未知异常，请联系系统管理者";
            logger.error("Common Exception:{}", e);
        }
        return Msg.err(resultCodeEnum, message);
    }

    /**
     * 获取错误信息
     * @param ex
     * @return
     */
    private String getConstraintViolationErrMsg(Exception ex) {
        // validTest1.id: id必须为正数
        // validTest1.id: id必须为正数, validTest1.name: 长度必须在有效范围内
        String message = ex.getMessage();
        try {
            int startIdx = message.indexOf(": ");
            if (startIdx < 0) {
                startIdx = 0;
            }
            int endIdx = message.indexOf(", ");
            if (endIdx < 0) {
                endIdx = message.length();
            }
            message = message.substring(startIdx, endIdx);
            return message;
        } catch (Throwable throwable) {
            logger.info("ex caught", throwable);
            return message;
        }

    }

}
